/**
 * Created by xinxinran on 15/12/1.
 */
'use strict';
var commonUtil = require('./commonUtil'),
    dao = require('./GomokuDao').getDao(), userNameCache = {};

class GomokuClient{
    constructor(socket, manager){
        this.socket = socket;
        this.manager = manager;
        this.username = null;
        this.userInfo = null;
        this.roomNumber = 0;

        this.sessionId = commonUtil.uuid(16, 16);

        this.status = 0;

        this.statusDesc = '';

        this.runClient();
    }

    runClient(){
        var _this = this;
        this.socket.on('login', function(data){
            _this.username = data.username;



            dao.findByUserName(_this.username).then(function(userInfo){
                if(userNameCache[_this.username]){
                    _this.status = -1;
                    throw '该用户名已经登录, 不能重复登录';
                }else{
                    userNameCache[_this.username] = 1;
                }

                if(!userInfo){
                    userInfo = {
                        username : _this.username,
                        userId : commonUtil.uuid(16, 16),
                        winTimes : 0,
                        loseTimes : 0,
                        score : 0,
                        lastLogin : new Date()
                    };

                    return dao.saveUser(userInfo);
                }

                return userInfo;
            }).then(function(userInfo){

                _this.userInfo = userInfo;
                _this.socket.emit('userInfo', userInfo);
            }).catch(function(err){
                _this.sendNotice('登录错误', err, 'danger');
                console.error(err);
            });
        });

        this.socket.on('getRooms', function(){
           _this.socket.emit('rooms', {rooms : _this.manager.getRooms()} );
        });

        this.socket.on('joinRoom', function(data){
            var roomNum = data.roomNumber;
            _this.roomNumber = roomNum;
            _this.manager.joinRoom(roomNum, data.mode, _this.sessionId);
        });

        this.socket.on('leaveRoom', function(){
            var roomNum = _this.roomNumber;
            _this.roomNumber = 0;
            _this.manager.leaveRoom(roomNum, _this.sessionId);
        });

        this.socket.on('start', function(){
            _this.manager.getReady(_this.roomNumber, _this.sessionId);
        });

        this.socket.on('putChess', function(data){
            _this.manager.playStep(_this.roomNumber, data.x, data.y, data.t);
        });

        this.socket.on('resetChess', function(){
            _this.socket.emit('resetChess', _this.manager.getRoomChessMap(_this.roomNumber));
        });

        this.socket.on('chessBack', function(){
            _this.manager.requestBack(_this.roomNumber, _this);
        });

        this.socket.on('confirmBack', function(backData){
            _this.manager.backChess(_this.roomNumber, backData.t, backData.s);
        });

        this.socket.on('cancelBack', function(backData){
            _this.manager.cancelBack(_this.roomNumber, backData.t, backData.s);
        });

        this.socket.on('chessDraw', function(){
            _this.manager.requestDraw(_this.roomNumber, _this.sessionId);
        });

        this.socket.on('confirmDraw', function(drawData){
            _this.manager.drawGame(_this.roomNumber, drawData.t, drawData.s);
        });

        this.socket.on('cancelDraw', function(drawData){
            _this.manager.cancelDraw(_this.roomNumber, drawData.t, drawData.s);
        });

        this.socket.on('chessLose', function(){
            _this.manager.myLose(_this.roomNumber, _this.sessionId);
        });

        this.socket.on('forceLeaveRoom', function(){
            var roomNum = _this.roomNumber, uInfo;
            _this.roomNumber = 0;
            _this.manager.leaveRoom(roomNum, _this.sessionId);

            dao.findByUserName(_this.username).then(function(userInfo){
                userInfo.score += -5;
                uInfo = userInfo.toObject();
                return dao.updateUser(userInfo);
            }).then(function(){
                _this.userInfo = uInfo;
            }).catch(function(err){
                console.error(err);
                _this.sendNotice('战绩更新错误', err, 'danger');
            });
        });

        this.socket.on('chatSend', function(chatObj){
            _this.manager.roomChat(_this.roomNumber, _this.username, chatObj.content);
        });
    }

    destroy(){
        if(this.status > -1){
            delete userNameCache[this.username];
        }
    }

    updateResult (rs){
        var _this = this, uInfo;
        dao.findByUserName(this.username).then(function(userInfo){
            userInfo.winTimes += rs;
            userInfo.loseTimes += (rs < 0 ? 1 : 0);
            userInfo.score += (rs < 0 ? -2 : (rs === 0 ? 1 : 3));

            uInfo = userInfo.toObject();
            return dao.updateUser(userInfo);
        }).then(function(){
            _this.userInfo = uInfo;
        }).catch(function(err){
            console.error(err);
            _this.sendNotice('战绩更新错误', err, 'danger');
        });
    }

    enterRoom (roomObj){

        this.socket.emit('enterRoom', {
            p1 : roomObj.firstPlayer.userInfo,
            p2 : roomObj.secondPlayer.userInfo,
            roomName : roomObj.roomName,
            roomNumber : roomObj.roomNumber,
            p1rs : roomObj.roomP1Scroe,
            p2rs : roomObj.roomP2Score,
            p1st : roomObj.p1Status,
            p2st : roomObj.p2Status
        });
    }

    sendGameCommand (cmd, data){
        this.socket.emit(cmd, data);
    }

    outRoom (roomObj){
        this.socket.emit('outRoom', {roomNumber : roomObj.roomNumber});
    }

    pushRoom(rooms){
        this.socket.emit('rooms', {rooms : rooms || this.manager.getRooms()} );
    }

    notifyPlayerStatus(roomObj){
        var p1Color = '', p2Color = '', p1Active = '', p2Active = '', gamer = roomObj.gamer;
        if(gamer.p1Color === 1){
            p1Color = 'black';
        }else if(gamer.p1Color === 2){
            p1Color = 'white';
        }

        if(gamer.p2Color === 1){
            p2Color = 'black';
        }else if(gamer.p2Color === 2){
            p2Color = 'white';
        }

        if(gamer.nowColor === gamer.p1Color){
            p1Active = 'active';
        }else if(gamer.nowColor === gamer.p2Color){
            p2Active = 'active';
        }

        this.socket.emit('playerState', {
            p1 : roomObj.firstPlayer.userInfo,
            p2 : roomObj.secondPlayer.userInfo,
            roomName : roomObj.roomName,
            roomNumber : roomObj.roomNumber,
            p1rs : roomObj.roomP1Scroe,
            p2rs : roomObj.roomP2Score,
            p1st : roomObj.p1Status,
            p2st : roomObj.p2Status,
            colorDesc1 : p1Color,
            colorDesc2 : p2Color,
            activeDesc1 : p1Active,
            activeDesc2 : p2Active,
            playingDesc1 : roomObj.firstPlayer.statusDesc || '对战中...',
            playingDesc2 : roomObj.secondPlayer.statusDesc || '对战中...'
        });
    }

    sendNotice (title, content, type){
        this.socket.emit('sysNotice', {noticeType : type || 'muted', title : title, content : content} );
    }

    sendMessage (username, type, pos ,content){
        this.socket.emit('roomMsg', {username : username, type : type, pos : pos, content : content} );
    }
}

module.exports = GomokuClient;